package com.bieyang.anjia.jpush;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import com.bieyang.anjia.R;
import com.bieyang.anjia.module.Device;
import com.bieyang.anjia.module.FileModel;
import com.bieyang.anjia.module.LoginTypeEnum;
import com.bieyang.anjia.module.NewsInfo;
import com.bieyang.anjia.module.User;
import com.bieyang.anjia.sqlitedatabase.AnjiaSQLiteOpenHelper;
import com.bieyang.anjia.sqlitedatabase.SqliteOperation;
import com.bieyang.anjia.ui.activity.AcAnxinAthome;
import com.bieyang.anjia.ui.activity.AcFindNewsDetail;
import com.bieyang.anjia.ui.activity.AcLogin;
import com.bieyang.anjia.ui.activity.AcTiYan;
import com.bieyang.anjia.ui.activity.App;
import com.bieyang.anjia.ui.activity.PubService;
import com.bieyang.anjia.utils.Constants;
import com.bieyang.anjia.utils.SharedPrefsUtil;
import com.bieyang.anjia.utils.Show;
import com.bieyang.anjia.utils.SubUtils;
import com.bieyang.anjia.utils.Util;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import cn.jpush.android.api.JPushInterface;
import cn.jpush.android.service.PushService;

/**
 * 自定义接收器
 * 
 * 如果不定义这个 Receiver，则： 1) 默认用户会打开主界面 2) 接收不到自定义消息
 */
@SuppressLint("SimpleDateFormat")
public class MyReceiver extends BroadcastReceiver {
	ArrayList<String> filePathArr = new ArrayList<String>();
	private static final String NET_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
	private static final String TAG = "JPush";
	private SqliteOperation sqliteOperation;
	private Context context;
	private SubUtils subUtils = new SubUtils();
	String netType = "";

	String lVersion;
	@SuppressLint("HandlerLeak")
	private Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case Constants.QUERY_SUB_SET_SUCCESS:

				Device device = (Device) msg.obj;
				if (null != device) {
					subUtils.saveSubSet(device, context);
					context.sendBroadcast(new Intent(Constants.UPDATE_SETTING));
				}
				break;
			case Constants.QUERY_SUB_SET_FAILED:
				break;
			case Constants.GET_URL_SUCCESS:
				FileModel model = (FileModel) msg.obj;
				if (null != model) {
					update(model);
				}
				break;
			case Constants.GET_URL_FAILED:
				break;
			case 101:
				downLoadAndSaveinfo((FileModel) msg.obj);
				break;
			case 111:
				break;
			default:
				break;
			}
		};
	};

	@Override
	public void onReceive(Context context, Intent intent) {
		this.context = context;
		if (null == App.mContext)
			App.mContext = context.getApplicationContext();
		if (null == sqliteOperation) {
			sqliteOperation = new SqliteOperation(context,
					AnjiaSQLiteOpenHelper.dbName, AnjiaSQLiteOpenHelper.version);
		}
		Bundle bundle = intent.getExtras();
		if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
			Log.d("boot", "intent.getAction()=" + intent.getAction() + "");
			Intent pushService = new Intent(context, PushService.class);
			context.startService(pushService);
		} else if (NET_ACTION.equals(intent.getAction())) {
			ConnectivityManager manager = (ConnectivityManager) context
					.getSystemService(Context.CONNECTIVITY_SERVICE);
			NetworkInfo info = manager.getActiveNetworkInfo();
			if (null == info) {
				return;
			}
			if (!intent.getBooleanExtra(
					ConnectivityManager.EXTRA_NO_CONNECTIVITY, false)) {
				login(context);
			} else {
				netType = info.getTypeName();
			}

		} else {
			Log.d(TAG, "[MyReceiver] onReceive - " + intent.getAction()
					+ ", extras: " + printBundle(bundle));

			if (JPushInterface.ACTION_REGISTRATION_ID
					.equals(intent.getAction())) {
				String regId = bundle
						.getString(JPushInterface.EXTRA_REGISTRATION_ID);
				Log.d(TAG, "[MyReceiver] 接收Registration Id : " + regId);
				// send the Registration Id to your server...
				SharedPrefsUtil.putValue(context.getApplicationContext(),
						AcLogin.REGISTRATION_ID, regId);

			} else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent
					.getAction())) {
				String msg = bundle.getString(JPushInterface.EXTRA_MESSAGE);
				Log.d(TAG, "[MyReceiver] 接收到推送下来的自定义消息: " + msg);
				Log.d("ReConnect", "[MyReceiver] 接收到推送下来的自定义消息: " + msg);

				doMsg(msg, context);

			} else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED
					.equals(intent.getAction())) {
				Log.d(TAG, "[MyReceiver] 接收到推送下来的通知");
				int notifactionId = bundle
						.getInt(JPushInterface.EXTRA_NOTIFICATION_ID);
				Log.d(TAG, "[MyReceiver] 接收到推送下来的通知的ID: " + notifactionId);

			} else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent
					.getAction())) {
				Log.d(TAG, "[MyReceiver] 用户点击打开了通知");

				// 打开自定义的Activity
				Intent i = new Intent(context, AcLogin.class);
				i.putExtras(bundle);
				// i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
						| Intent.FLAG_ACTIVITY_CLEAR_TOP);
				context.startActivity(i);

			} else if (JPushInterface.ACTION_RICHPUSH_CALLBACK.equals(intent
					.getAction())) {
				Log.d(TAG,
						"[MyReceiver] 用户收到到RICH PUSH CALLBACK: "
								+ bundle.getString(JPushInterface.EXTRA_EXTRA));
				// 在这里根据 JPushInterface.EXTRA_EXTRA 的内容处理代码，比如打开新的Activity，
				// 打开一个网页等..

			} else if (JPushInterface.ACTION_CONNECTION_CHANGE.equals(intent
					.getAction())) {
				boolean connected = intent.getBooleanExtra(
						JPushInterface.EXTRA_CONNECTION_CHANGE, false);
				Log.w(TAG, "[MyReceiver]" + intent.getAction()
						+ " connected state change to " + connected);
			} else {
				Log.d(TAG,
						"[MyReceiver] Unhandled intent - " + intent.getAction());
			}
		}
	}

	/**
	 * 登录
	 * 
	 * @param con
	 */
	private void login(Context con) {
		// System.out.println("执行重新登录");
		if (!SharedPrefsUtil.getBooleanValue(con, "subIsLogin", false)
				&& !App.isLogin) {
			return;
		}
		String phone = SharedPrefsUtil.getStringValue(context, "phone", null);
		String password = SharedPrefsUtil.getStringValue(context, "password",
				null);
		String uuid = SubUtils.getUuid(con);
		String type = SharedPrefsUtil.getStringValue(context, "loginType", "M");
		if (null != phone && null != password) {
			User user = new User();
			user.setCardNo(phone);
			user.setPassword(password);
			user.setUuid(uuid);
			if ("M".equals(type)) {
				user.setType(LoginTypeEnum.MAIN);
			} else {
				user.setType(LoginTypeEnum.CLIENT);
			}
			App.netManager.login(con, user, mHandler);
		}

	}

	private void doMsg(String msg, final Context context) {

		String msgArr[] = msg.split(";");
		int code = Integer
				.parseInt(msgArr[0].substring(msgArr[0].indexOf(":") + 1));
		// 1,账号被登陆,2,忠机名被修改,3,资讯,4,忠机设置,5报警6.删除忠机,7松开,8按下,9版本更新
		switch (code) {
		case 1:
			logout(context);
			break;
		case 2:
			String name = msgArr[1].substring(msgArr[1].indexOf(":") + 1);
			SharedPrefsUtil.putValue(context, "deviceName", name);
			context.sendBroadcast(new Intent(Constants.UPDATE_NAME));
			break;
		case 3:// news
				// String title = msgArr[1].substring(msgArr[1].indexOf(":") +
				// 1);
				// // 显示到通知栏
				// SubUtils.showNotification(title, title, context,
				// AcFindNews.class);
			getNewsNotify(context, msg);
			break;
		case 4:
			updateSetting(context);
			break;
		case 5:

			subAlarm(context, msg);
			break;
		case 6:
			if (msgArr[1].substring(msgArr[1].indexOf(":") + 1).equals(
					SharedPrefsUtil.getStringValue(context, "memberId", "0"))) {
				context.sendBroadcast(new Intent(Constants.DELETE_SUB));
			}
			break;
		case 7:
			// context.sendBroadcast(new Intent(VideoUI.ACTION_UP));
			break;
		case 8:
			// context.sendBroadcast(new Intent(VideoUI.ACTION_DOWM));
			break;
		case 9:// alarm push

			String data = msgArr[1];// .substring(1, msgArr[1].length()-1);
			JsonObject root = new JsonParser().parse(data).getAsJsonObject();

			App.verinfo.sNewVerNo = root.get("version").getAsString(); // ftp
																		// version
																		// No.
			lVersion = Util.getVersionName(App.mContext); // local version No.

			if (!Util.compareVersion(lVersion, App.verinfo.sNewVerNo)) {
				return;
			}

			App.verinfo.iFileSize = root.get("size").getAsInt();
			App.verinfo.sUpDownLinkAddr = root.get("url").getAsString();
			App.verinfo.sUpMsg = root.get("content").getAsString();
			App.verinfo.sFileName = "anjia.apk";

			int typeUpgrade = root.get("typeCode").getAsInt();
			switch (typeUpgrade) {
			case 1: // 创可贴更新,主机主界面菜单按钮红点提示
				SharedPrefsUtil.putValue(App.mContext, "newVersion", 2);
				break;
			case 2:// 弹窗升级
				SharedPrefsUtil.putValue(App.mContext, "newVersion", 2);

				break;
			case 3:// 强制更新
				SharedPrefsUtil.putValue(App.mContext, "newVersion", 3);

				break;

			default:
				break;
			}

			String title = context.getString(R.string.push_new_version);
			SubUtils.showNotification(title, title, context, AcTiYan.class);

			break;

		default:
			break;
		}
	}

	/** 退出 */
	private void logout(Context context) {
		// 执行注销工作
		PubService.isrun = false;
		App.isLogin = false;
		SharedPrefsUtil.putValue(App.mContext, "loginMain", false);
		// 显示到通知栏
		SubUtils.showNotification(context.getString(R.string.tip_more_account),
				context.getString(R.string.tip_more_account), context,
				AcLogin.class);
		context.sendBroadcast(new Intent(Constants.LOGIN_OTHER));
	}

	/** 接收到修改忠机配置消息 */
	private void updateSetting(final Context context) {
		Device device = new Device();
		device.setUuid(SubUtils.getUuid(context));
		device.setMemberId(SharedPrefsUtil.getStringValue(context, "memberId",
				"0"));
		App.netManager.queryCollectionTerminal(device, mHandler);
	}

	/** 接收到资讯信息 */
	private void getNewsNotify(Context con, String msg) {
		String strArr[] = msg.split(";");
		String data = strArr[1].substring(strArr[1].indexOf(":") + 1);
		try {
			JSONObject json = new JSONObject(data);
			int id = json.getInt("id");
			String pictureUrl = json.getString("picture");
			String title = json.getString("title");
			String content = json.getString("content");
			String webUrl = json.getString("url");
			String submitTime = json.getString("published");

			NewsInfo newsInfo = new NewsInfo();
			newsInfo.newsId = id;
			newsInfo.title = title;
			newsInfo.content = content;
			newsInfo.webUrl = webUrl;
			newsInfo.submitTime = submitTime;
			newsInfo.pictureUrl = pictureUrl;

			SqliteOperation sqlOperation = new SqliteOperation(con,
					AnjiaSQLiteOpenHelper.dbName, AnjiaSQLiteOpenHelper.version);
			sqlOperation.newsInsert(newsInfo);
			SharedPrefsUtil.putValue(con, "weburl", webUrl);
			SubUtils.showNotification(title, title, con, AcFindNewsDetail.class);

		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/** 接收到报警消息 */
	private void subAlarm(Context con, String msg) {
		String strArr[] = msg.split(";");
		String data = strArr[1].substring(strArr[1].indexOf(":") + 1);
		try {
			JSONObject json = new JSONObject(data);
			subUtils.saveDataToDataBase(context, sqliteOperation, json);

			String name = json.getString("name");
			String uuid = json.getString("uuid");
			if (!"null".equals(name) && uuid.length() > 10) {
				name = uuid.substring(uuid.length() - 10);
			} else {
				name = "";
			}
			FileModel model = new FileModel();
			model.uuid = json.getString("uuid");
			String alarmType = json.getString("alarmType");
			if (alarmType.equals("HUMAN_RECOGNITION")) {
				alarmType = con.getString(R.string.sub_body_recg);
			} else if (alarmType.equals("MOTION_DETECTION")) {
				alarmType = con.getString(R.string.sub_dys);
			} else if (alarmType.equals("ZHONG_MOVING")) {
				alarmType = con.getString(R.string.sub_moved);
			}
			model.alarmType = alarmType;
			String time = json.get("alarmTime").toString();
			model.time = time;
			model.memberId = json.getString("memberId");
			model.alarmId = json.getInt("alarmId");
			model.name = name;
			App.netManager.getAlarmUrl(model, mHandler);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// 打印所有的 intent extra 数据
	private static String printBundle(Bundle bundle) {
		StringBuilder sb = new StringBuilder();
		for (String key : bundle.keySet()) {
			if (key.equals(JPushInterface.EXTRA_NOTIFICATION_ID)) {
				sb.append("\nkey:" + key + ", value:" + bundle.getInt(key));
			} else if (key.equals(JPushInterface.EXTRA_CONNECTION_CHANGE)) {
				sb.append("\nkey:" + key + ", value:" + bundle.getBoolean(key));
			} else {
				sb.append("\nkey:" + key + ", value:" + bundle.getString(key));
			}
		}
		return sb.toString();
	}

	private void update(FileModel model) {
		final String urlPath = model.urlPath;
		Log.d("urlPath", model.urlPath);
		sqliteOperation.update("alarminfo", "alarmtime = ? and uuid = ?",
				new String[] { model.time, model.uuid }, "urlpath", urlPath);
		sqliteOperation.update("alarminfo", "alarmtime = ? and uuid = ?",
				new String[] { model.time, model.uuid }, "filetype",
				model.fileType);
		String strArr[] = urlPath.split(";");
		String fileType = model.fileType;
		if (fileType.equals(".mp4")) {
			model.alarmMethod = "video";
		} else {
			if (strArr.length > 1) {
				model.alarmMethod = "three";
			} else {
				model.alarmMethod = "one";
			}
		}
		sqliteOperation.update("alarminfo", "alarmtime = ? and uuid = ?",
				new String[] { model.time, model.uuid }, "alarmmethod",
				model.alarmMethod);

		if (null != urlPath && !"null".equals(urlPath)) {
			getLocalPath(model);
		}

	}

	/**
	 * 生成本地文件路径
	 * 
	 * @param position
	 *            位置
	 * @param urlPath
	 *            下载路径
	 */
	private void getLocalPath(final FileModel model) {

		if (model.alarmMethod.equals("three")) {
			final String url[] = model.urlPath.split(";");
			new Thread(new Runnable() {
				@Override
				public void run() {
					Looper.prepare();
					downLoad(url[0], model);
					Looper.loop();
				}
			}).start();
			new Thread(new Runnable() {
				@Override
				public void run() {
					Looper.prepare();
					downLoad(url[1], model);
					Looper.loop();
				}
			}).start();
			new Thread(new Runnable() {
				@Override
				public void run() {
					Looper.prepare();
					downLoad(url[2], model);
					Looper.loop();
				}
			}).start();
		} else {
			new Thread(new Runnable() {
				@Override
				public void run() {
					Looper.prepare();
					downLoad(model.urlPath, model);
					Looper.loop();
				}
			}).start();
		}
	}

	/**
	 * 文件下载
	 * 
	 * @param url
	 *            路径
	 * @param map
	 * @param position
	 *            list偏移量
	 */
	private void downLoad(String url, FileModel model) {
		Log.d("url", url + "");
		HttpClient httpClient = new DefaultHttpClient();
		// GET
		HttpGet myGet = new HttpGet(url);
		try {
			HttpResponse response = httpClient.execute(myGet);
			String fileName = getFileName(response);
			if (null == fileName) {
				Show.toast(context, R.string.down_load_failed);
				return;
			}
			String filepath = null;
			if (".mp4".equals(model.fileType)) {
				filepath = subUtils.getFileFloderPath(context) + fileName
						+ Constants.VIDEO_SUFFIX;
			} else {
				filepath = subUtils.getFileFloderPath(context) + fileName
						+ Constants.PICTURE_SUFFIX;
			}
			File file = new File(filepath);
			file.getParentFile().mkdirs();
			model.filePath = filepath;
			FileOutputStream fileout = new FileOutputStream(file);
			InputStream is = response.getEntity().getContent();
			byte[] buffer = new byte[1024];
			int ch = 0;
			while ((ch = is.read(buffer)) != -1) {
				fileout.write(buffer, 0, ch);
			}
			is.close();
			fileout.flush();
			fileout.close();
			if (model.alarmMethod.equals("three")) {
				filePathArr.add(filepath);
			}
			Message msg = Message.obtain();
			msg.what = 101;
			msg.obj = model;
			mHandler.sendMessage(msg);
		} catch (Exception e) {
			filePathArr.clear();
			mHandler.sendEmptyMessage(111);
			return;
		}
	}

	/**
	 * 获取response header中Content-Disposition中的filename值
	 * 
	 * @param response
	 * @return
	 */
	public static String getFileName(HttpResponse response) {
		Header contentHeader = response.getFirstHeader("Content-Disposition");
		String filename = null;
		if (contentHeader != null) {
			HeaderElement[] values = contentHeader.getElements();
			if (values.length == 1) {
				NameValuePair param = values[0].getParameterByName("filename");
				if (param != null) {
					try {
						filename = param.getValue();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}
		return filename;
	}

	private void downLoadAndSaveinfo(FileModel model) {
		int alarmCode = -1;
		if (model.alarmMethod.equals("three")) {
			if (filePathArr.size() != 3) {
				return;
			} else {
				model.filePath = filePathArr.get(0) + ";" + filePathArr.get(1)
						+ ";" + filePathArr.get(2);
			}
			alarmCode = 1;
		} else if (model.alarmMethod.equals("video")) {
			alarmCode = 0;
		} else if (model.alarmMethod.equals("one")) {
			alarmCode = 2;
		}
		sqliteOperation.update("alarminfo", "urlpath=?",
				new String[] { (String) model.urlPath }, "filepath",
				model.filePath);
		SharedPrefsUtil.putValue(context, "alarmCode", alarmCode);
		SharedPrefsUtil.putValue(context, "alarmName", model.name);
		SharedPrefsUtil.putValue(context, "alarmType", model.alarmType);
		SharedPrefsUtil.putValue(context, "alarmTime", model.time);
		SharedPrefsUtil.putValue(context, "alarmUuid", model.uuid);
		SharedPrefsUtil.putValue(context, "alarmPath", model.filePath);
		App.newNews = true;
		context.sendBroadcast(new Intent(Constants.NEW_NEWS));
		context.sendBroadcast(new Intent(Constants.ANXIN_NOTIFY));
		SubUtils.showNotification(model.alarmType,
				model.name + context.getString(R.string.alarm_happened),
				context, AcAnxinAthome.class);
		filePathArr.clear();
	}
}
